﻿namespace DotRas
{
    using DotRas.Design;
    using pptpclient.Properties;
    using System;
    using System.Collections.ObjectModel;
    using System.Reflection;

    public sealed class RasEntryCollection : RasOwnedCollection<RasPhoneBook, RasEntry>
    {
        private RasEntryItemCollection _lookUpTable;

        internal RasEntryCollection(RasPhoneBook owner) : base(owner)
        {
            this._lookUpTable = new RasEntryItemCollection();
        }

        internal void ChangeKey(RasEntry item, string newKey)
        {
            this._lookUpTable.ChangeKey(item, newKey);
        }

        protected override void ClearItems()
        {
            bool enableFileWatcher = false;
            try
            {
                enableFileWatcher = base.Owner.EnableFileWatcher;
                base.Owner.EnableFileWatcher = false;
                while (base.Count > 0)
                {
                    base.RemoveAt(0);
                }
            }
            finally
            {
                base.Owner.EnableFileWatcher = enableFileWatcher;
                if (!base.IsInitializing)
                {
                    this.Load();
                }
            }
        }

        public bool Contains(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                DotRas.ThrowHelper.ThrowArgumentException("name", Resources.Argument_StringCannotBeNullOrEmpty);
            }
            return this._lookUpTable.Contains(name);
        }

        protected override void InsertItem(int index, RasEntry item)
        {
            if (item == null)
            {
                DotRas.ThrowHelper.ThrowArgumentNullException("item");
            }
            if ((base.Owner == null) || string.IsNullOrEmpty(base.Owner.Path))
            {
                DotRas.ThrowHelper.ThrowInvalidOperationException(Resources.Exception_PhoneBookNotOpened);
            }
            item.Owner = base.Owner;
            if (base.IsInitializing)
            {
                this._lookUpTable.Insert(index, item);
            }
            else if (RasHelper.SetEntryProperties(base.Owner, item) && !base.Owner.EnableFileWatcher)
            {
                this._lookUpTable.Insert(index, item);
            }
            base.InsertItem(index, item);
        }

        internal void Load()
        {
            if (string.IsNullOrEmpty(base.Owner.Path))
            {
                DotRas.ThrowHelper.ThrowInvalidOperationException(Resources.Exception_PhoneBookNotOpened);
            }
            try
            {
                base.BeginLock();
                base.IsInitializing = true;
                base.Clear();
                NativeMethods.RASENTRYNAME[] entryNames = RasHelper.GetEntryNames(base.Owner);
                if ((entryNames != null) && (entryNames.Length > 0))
                {
                    for (int i = 0; i < entryNames.Length; i++)
                    {
                        NativeMethods.RASENTRYNAME rasentryname = entryNames[i];
                        RasEntry entryProperties = RasHelper.GetEntryProperties(base.Owner, rasentryname.name);
                        if (entryProperties != null)
                        {
                            base.Add(entryProperties);
                        }
                    }
                }
            }
            finally
            {
                base.IsInitializing = false;
                base.EndLock();
            }
        }

        public bool Remove(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                DotRas.ThrowHelper.ThrowArgumentException("name", Resources.Argument_StringCannotBeNullOrEmpty);
            }
            if (this.Contains(name))
            {
                RasEntry item = this[name];
                if (item != null)
                {
                    base.Remove(item);
                }
            }
            return false;
        }

        protected override void RemoveItem(int index)
        {
            if ((base.Owner == null) || string.IsNullOrEmpty(base.Owner.Path))
            {
                DotRas.ThrowHelper.ThrowInvalidOperationException(Resources.Exception_PhoneBookNotOpened);
            }
            if (!base.IsInitializing)
            {
                RasEntry entry = base[index];
                if (((entry != null) && RasHelper.DeleteEntry(entry.Owner.Path, entry.Name)) && !base.Owner.EnableFileWatcher)
                {
                    this._lookUpTable.RemoveAt(index);
                }
            }
            base.RemoveItem(index);
        }

        public RasEntry this[string name]
        {
            get
            {
                return this._lookUpTable[name];
            }
        }

        private class RasEntryItemCollection : KeyedCollection<string, RasEntry>
        {
            public void ChangeKey(RasEntry item, string newKey)
            {
                if (item == null)
                {
                    DotRas.ThrowHelper.ThrowArgumentNullException("item");
                }
                if (string.IsNullOrEmpty(newKey))
                {
                    DotRas.ThrowHelper.ThrowArgumentException("newKey", Resources.Argument_StringCannotBeNullOrEmpty);
                }
                base.ChangeItemKey(item, newKey);
            }

            protected override string GetKeyForItem(RasEntry item)
            {
                if (item == null)
                {
                    DotRas.ThrowHelper.ThrowArgumentNullException("item");
                }
                return item.Name;
            }
        }
    }
}

